using FireStarterModeller.BO;
using FireStarterModeller.Logic.Commands;
using FireStarterModeller.Test.BO;
using Habanero.Base.Exceptions;
using Habanero.BO;
using NUnit.Framework;
using ICommand=FireStarterModeller.Logic.Commands.ICommand;
using ICommandFactory=FireStarterModeller.Logic.Commands.ICommandFactory;

namespace FireStarterModeller.Test.Logic.Commands
{
    [TestFixture]
    public class TestDeleteAssemblyCommand
    {
        [TestFixtureSetUp]
        public void SetupFixture()
        {
            TestUtilsLogic.SetupFixture();
        }
        [SetUp]
        public void SetupTest()
        {
            TestUtilsLogic.SetupTest();
        }

        private static ICommandFactory CommandFactory
        {
            get { return new CommandFactory(); }
        }

        [Test]
        public void Test_Apply()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateSolutionWithNoAssemblies();
            DMAssembly assembly = dmSolution.CreateAssembly("Assembly1");
            assembly.Save();

            //---------------Assert preconditions---------------
            Assert.AreEqual(1, dmSolution.Assemblies.Count);
            //---------------Execute Test ----------------------
            ICommand command = CommandFactory.CreateDeleteAssembly(assembly);
            command.Apply();

            //---------------Test Result -----------------------
            Assert.AreEqual(0, dmSolution.Assemblies.Count);
            Assert.IsTrue(assembly.Status.IsDeleted);
        }

        [Test]
        public void Test_Apply_Failure_UnableToDelete()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateSolutionWithNoAssemblies();
            DMAssembly assembly = dmSolution.CreateAssembly("Assembly1");
            assembly.CreateClass("Class1");
            dmSolution.Save();

            //---------------Execute Test ----------------------
            try
            {
                ICommand command = CommandFactory.CreateDeleteAssembly(assembly);
                command.Apply();
                Assert.Fail("Should have raised error because the assembly has at least one class in it");
                //---------------Test Result -----------------------
            }
            //catch (BusinessObjectReferentialIntegrityException ex)
            catch (BusObjDeleteException ex)
            {
                //StringAssert.Contains("There are 1 objects related through the 'Classes' relationship that need to be deleted first.", ex.Message);
                StringAssert.Contains("The assembly '" + assembly.ToString() + "' cannot be deleted as there are 1 objects related through the 'Classes' relationship that need to be deleted first.", ex.Message);
            }
            Assert.AreEqual(1, dmSolution.Assemblies.Count);
            Assert.AreEqual(1, assembly.Classes.Count);
            //---------------Tear Down -------------------------          
        }


        [Test]
        public void Test_Revert()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateSolutionWithNoAssemblies();
            DMAssembly assembly = dmSolution.CreateAssembly("Assembly1");
            assembly.Save();

            ICommand command = CommandFactory.CreateDeleteAssembly( assembly);
            command.Apply();

            //---------------Assert Precondition----------------
            Assert.AreEqual(0, dmSolution.Assemblies.Count);
            Assert.IsTrue(assembly.Status.IsDeleted);

            //---------------Execute Test ----------------------
            command.Revert();

            //---------------Test Result -----------------------
            Assert.AreEqual(1, dmSolution.Assemblies.Count);
            Assert.IsFalse(assembly.Status.IsDeleted);
            Assert.IsFalse(assembly.Status.IsNew);
            Assert.IsFalse(assembly.Status.IsDirty);
        }

        private static DMSolution CreateSolutionWithNoAssemblies()
        {
            DMSolution dmSolution = TestUtilsShared.CreateSavedDMSolution();
            dmSolution.SolutionName = "Solution1-" + dmSolution.SolutionName;
            dmSolution.Assemblies.MarkForDeleteAt(0);
            dmSolution.Save();
            return dmSolution;
        }

    }
}
